package com.party.notify.notifyPush.servce.impl;

import com.party.common.constant.Constant;
import com.party.common.utils.StringUtils;
import com.party.core.exception.BusinessException;
import com.party.core.model.YesNoStatus;
import com.party.core.model.member.MemberGroup;
import com.party.core.model.member.PackageCount;
import com.party.core.model.notify.*;
import com.party.core.model.system.TargetType;
import com.party.core.service.member.IMemberGroupService;
import com.party.core.service.member.IPackageCountService;
import com.party.core.service.notify.IEventChannelService;
import com.party.core.service.notify.IEventService;
import com.party.notify.appNotify.service.IAppNotifyService;
import com.party.notify.appPush.service.IPushService;
import com.party.notify.email.service.IEmailService;
import com.party.notify.notifyPush.officialPartner.IOfficialPartnerNotifySendService;
import com.party.notify.notifyPush.servce.INotifyService;
import com.party.notify.sms.service.ISmsService;
import com.party.notify.template.service.ITemplateService;
import com.party.notify.wechatNotify.service.IWechatNotifyService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;

/**
 * 系统消息服务接口
 * User: wei.li
 * Date: 2017/4/5
 * Time: 22:41
 */

@Service
public class NotifyService implements INotifyService {

    @Autowired
    private IEventService eventService;


    @Autowired
    private IEventChannelService eventChannelService;

    @Autowired
    private ISmsService smsService;

    @Autowired
    private IAppNotifyService appNotifyService;

    @Autowired
    private IPushService pushService;

    @Autowired
    private IEmailService emailService;

    @Autowired
    private IWechatNotifyService wechatNotifyService;

    @Autowired
    private IMemberGroupService memberGroupService;

    @Autowired
    private IOfficialPartnerNotifySendService officialPartnerNotifySendService;

    @Autowired
    private IPackageCountService packageCountService;

    @Autowired
    private ITemplateService templateService;

    protected static Logger logger = LoggerFactory.getLogger(NotifyService.class);

    /**
     * 消息推送
     * @param eventCode 时间编码
     * @param telephone 电话号
     * @param authorId 作者编号
     * @param content 内容
     * @param template 模板编号
     */
    public void push(String eventCode, String telephone, String authorId, HashMap<String, Object> content,
                     String template, String appKey, String secret) {
        Event event = eventService.findByCode(eventCode);
        if (null == event){
            throw new BusinessException("消息发送异常，消息事件不存在");
        }

        //事件开关
        if (YesNoStatus.NO.getCode().equals(event.getMsgSwitch())){
            return;
        }

        // 短信发送
        EventChannel sEventChannel = eventChannelService.findByChannelCodeAndEventId(Constant.MESSAGE_CHANNEL_SMS,event.getId());
        if (null != sEventChannel) {
            if (YesNoStatus.YES.getCode().equals(sEventChannel.getChannelSwitch())) {
                if (StringUtils.isEmpty(telephone)) {
                    if (StringUtils.isNotEmpty(template)) {
                        logger.error("短信发送失败，没有收信人手机号；短信内容为：{}", templateService.replace(template, content));
                    } else {
                        logger.error("短信发送失败，没有收信人手机号；短信内容为：{}", templateService.replace(sEventChannel.getTemplate(), content));
                    }
                } else {
                    Integer isNewFlag = Instance.FLAG_NO; // 记录标志位
                    Integer isPermitFlag = YesNoStatus.YES.getCode(); // 是否允许发送

                    String orgId = "";
                    Object way = content.get(InstanceConstant.WAY); // 发送方式 SYSTEM：系统 ORGANIZATION：机构
                    Object isActivePush = content.get(InstanceConstant.IS_ACTIVE_PUSH); // 是否主动推送 null表示不是主动推送
                    if (null != way && InstanceWay.ORGANIZATION.getName().equals(way)) {
                        Object senderId = content.get(InstanceConstant.SENDER_ID); // 机构id
                        orgId = senderId != null ? senderId.toString() : "";
                    }

                    if (StringUtils.isNotEmpty(orgId)) { // 只有标志为机构发送的短信才需要费用控制
                        PackageCount packageCount = packageCountService
                                .getUnique(new PackageCount(orgId, TargetType.PUSH_SMS.getCode()));
                        // 短信控制的开关已打开，才需记录短信发送标志位
                        if (null != packageCount && YesNoStatus.YES.getCode().equals(packageCount.getIsOpen())) {
                            // 剩余可用数量 = 累计短信总数 - 已使用数量（合作商标志的发送成功短信）
                            Integer spareNum = packageCount.getTotalNum() - packageCount.getUseNum();
                            if (spareNum > Integer.valueOf(0)) { // 数量足够允许发
                                isNewFlag = Instance.FLAG_YES;
                            } else { // 数量不够并且没有预警过
                                if (spareNum.equals(Integer.valueOf(0)) && YesNoStatus.NO_NEW.getCode().equals(packageCount.getIsWarned())) {
                                    try {
                                        // 为0时，发送短信提醒充值
                                        MemberGroup member = memberGroupService.get(packageCount.getMemberId());
                                        officialPartnerNotifySendService.sendSmsWarn(member.getRealname(),
                                                member.getMobile(), packageCount.getMemberId(), spareNum);
                                    } catch (Exception e) {
                                        logger.error("机构短信收费预警异常", e);
                                    }

                                    try {
                                        packageCountService.updateWarn(packageCount);
                                    } catch (Exception e) {
                                        logger.error("机构更改预警字段异常——机构id" + orgId, e);
                                    }
                                }
                                // null表示不是主动推送 是否允许超出短信发送
                                if (null == isActivePush && packageCount.getIsAllowExcess().equals(YesNoStatus.YES.getCode())) {
                                    isNewFlag = Instance.FLAG_YES;
                                } else {
                                    // Integer excessNum = packageCount.getExcessNum(); // 允许超出数量 暂时不用
                                    if (packageCount.getUseNum() < (packageCount.getTotalNum())) {
                                        isNewFlag = Instance.FLAG_YES;
                                    } else {
                                        isNewFlag = Instance.FLAG_NOT_CAN; // 余额不足标志位
                                        isPermitFlag = YesNoStatus.NO_NEW.getCode();
                                    }
                                }
                            }
                        }
                    }

                    content.put(InstanceConstant.IS_NEW_FLAG, isNewFlag);
                    content.put(InstanceConstant.IS_PERMIT_FLAG, isPermitFlag);
                    if (null != template) {
                        String templateId = (String) content.get("templateId");
                        smsService.push(true, authorId, template, templateId, telephone, content);
                    } else {
                        boolean isWrite = sEventChannel.getWriteSwitch().equals(1);
                        smsService.push(isWrite, authorId, sEventChannel.getTemplate(), sEventChannel.getId(), telephone, content);
                    }
                }
            }
        }

        // 系统消息
        EventChannel aEventChannel = eventChannelService.findByChannelCodeAndEventId(Constant.MESSAGE_CHANNEL_APP, event.getId());
        if (null != aEventChannel){
            if (YesNoStatus.YES.getCode().equals(aEventChannel.getChannelSwitch())){
                appNotifyService.push(aEventChannel.getTemplate(), authorId, event.getType(), content);
            }
        }

        // jpush发送
        EventChannel jEventChannel = eventChannelService.findByChannelCodeAndEventId(Constant.MESSAGE_CHANNEL_JPUSH, event.getId());
        if (null != jEventChannel){
            if (YesNoStatus.YES.getCode().equals(jEventChannel.getChannelSwitch())){
                boolean isWrite = jEventChannel.getWriteSwitch().equals(1);
                pushService.push(isWrite, jEventChannel.getTemplate(), authorId, event.getType(), content, appKey, secret);
            }
        }

        // 微信公众号模板消息
        EventChannel wEventChannel = eventChannelService.findByChannelCodeAndEventId(Constant.MESSAGE_CHANNEL_WECHAT, event.getId());
        if (null != wEventChannel){
            if (YesNoStatus.YES.getCode().equals(wEventChannel.getChannelSwitch())){
                boolean isWrite = wEventChannel.getWriteSwitch().equals(1);
                try {
                    wechatNotifyService.push(isWrite, content);
                } catch (Exception e) {
                    logger.debug("微信公众号模板消息推送异常", e);
                }
            }
        }
        // 微信小程序模板消息
        EventChannel wXcxEventChannel = eventChannelService.findByChannelCodeAndEventId(Constant.MESSAGE_CHANNEL_WECHAT_XCX, event.getId());
        if (null != wXcxEventChannel) {
            if (YesNoStatus.YES.getCode().equals(wXcxEventChannel.getChannelSwitch())) {
                boolean isWrite = wXcxEventChannel.getWriteSwitch().equals(1);
                try {
                    wechatNotifyService.pushXcxMessage(isWrite, content);
                } catch (Exception e) {
                    logger.debug("微信小程序模板消息推送异常", e);
                }
            }
        }

        // 邮件发送
        EventChannel eEventChannel = eventChannelService.findByChannelCodeAndEventId(Constant.MESSAGE_CHANNEL_EMAIL, event.getId());
        if (null != eEventChannel){
            if (YesNoStatus.YES.getCode().equals(eEventChannel.getChannelSwitch())){
                emailService.push();
            }
        }
    }

    /**
     * 消息推送
     * @param eventCode 事件编号
     * @param telephone 电话号
     * @param authorId 作者编号
     * @param content 内容
     */
    public void push(String eventCode, String telephone, String authorId, HashMap<String, Object> content) {
        this.push(eventCode, telephone, authorId, content, null);
    }

    /**
     * 消息推送
     * @param eventCode 时间编号
     * @param content 内容
     */
    public void push(String eventCode, String authorId, HashMap<String, Object> content) {
        this.push(eventCode, null, authorId, content);
    }


    /**
     * 消息推送
     * @param eventCode 时间编码
     * @param telephone 电话号
     * @param authorId 作者编号
     * @param content 内容
     * @param template 模板编号
     */
    public void push(String eventCode, String telephone, String authorId, HashMap<String, Object> content, String template) {
        this.push(eventCode, telephone, authorId, content, template, null, null);
    }
}
